package com.walkline.weibo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.microedition.io.HttpConnection;

import localization.WeiboSDKResource;
import net.rim.blackberry.api.browser.URLEncodedPostData;
import net.rim.device.api.browser.field2.BrowserField;
import net.rim.device.api.browser.field2.BrowserFieldRequest;
import net.rim.device.api.i18n.ResourceBundle;
import net.rim.device.api.io.http.HttpProtocolConstants;
import net.rim.device.api.io.transport.ConnectionDescriptor;
import net.rim.device.api.io.transport.ConnectionFactory;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.UiApplication;

import org.json.me.JSONException;
import org.json.me.JSONObject;
import org.json.me.JSONTokener;
import org.w3c.dom.Document;

import com.walkline.app.WeiboAppConfig;
import com.walkline.util.Enumerations.BaseApp;
import com.walkline.util.Enumerations.Feature;
import com.walkline.util.Enumerations.TrimUser;
import com.walkline.util.Enumerations.UserList;
import com.walkline.util.Function;
import com.walkline.util.ImageItem;
import com.walkline.util.StringUtility;
import com.walkline.util.network.HttpClient;
import com.walkline.util.network.MyConnectionFactory;
import com.walkline.util.ui.BrowserScreen;
import com.walkline.weibo.dao.WeiboAccount;
import com.walkline.weibo.dao.WeiboComment;
import com.walkline.weibo.dao.WeiboCommentWrapper;
import com.walkline.weibo.dao.WeiboFavorite;
import com.walkline.weibo.dao.WeiboFavoriteWrapper;
import com.walkline.weibo.dao.WeiboGroupListWrapper;
import com.walkline.weibo.dao.WeiboRemind;
import com.walkline.weibo.dao.WeiboRepostWrapper;
import com.walkline.weibo.dao.WeiboStatus;
import com.walkline.weibo.dao.WeiboStatusWrapper;
import com.walkline.weibo.dao.WeiboSuggestionWrapper;
import com.walkline.weibo.dao.WeiboTagsWrapper;
import com.walkline.weibo.dao.WeiboUser;
import com.walkline.weibo.dao.WeiboUserWrapper;
import com.walkline.weibo.inf.Account;
import com.walkline.weibo.inf.Comment;
import com.walkline.weibo.inf.CommentWrapper;
import com.walkline.weibo.inf.Favorite;
import com.walkline.weibo.inf.FavoriteWrapper;
import com.walkline.weibo.inf.GroupListWrapper;
import com.walkline.weibo.inf.Remind;
import com.walkline.weibo.inf.RepostWrapper;
import com.walkline.weibo.inf.Status;
import com.walkline.weibo.inf.StatusWrapper;
import com.walkline.weibo.inf.SuggestionWrapper;
import com.walkline.weibo.inf.TagsWrapper;
import com.walkline.weibo.inf.User;
import com.walkline.weibo.inf.UserWrapper;

public class WeiboSDK implements WeiboSDKResource
{
	private static ResourceBundle _bundle = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);

	private Object ACCESS_TOKEN_LOCK = new Object();
	private WeiboAppConfig _appConfig;
	private Remind _reminds;
	private HttpClient http;

	private String _accessToken = null;
	private long _expireTimeMillis = 0;
	private String _uid = "";
	private String _id = "";
	private String _pwd = "";
	private boolean _autoMode = true;
	//private boolean _is_exclusive = false; // Integer.toHexString(DeviceInfo.getDeviceId()).toUpperCase().equals("29337DFA");

	public static String APP_KEY = WeiboConfig.client_IDS[0];
	public static String APP_SECRET = WeiboConfig.client_SECRETS[0];
	public static String REDIRECT_URI = "";

	//public static String STATUS_COUNT = "20";
	public static int REPOST_COUNT = 20;
	//public static String SUGGESTION_COUNT = "20";

	public static WeiboSDK getInstance() {return new WeiboSDK();}

	protected WeiboSDK() {http = new HttpClient(new MyConnectionFactory());}

	public WeiboAppConfig getAppConfig() {return _appConfig;}

	public void setAppConfig(WeiboAppConfig appConfig) {_appConfig = appConfig;}

	public Remind getReminds() {return _reminds;}

	public void setReminds(Remind reminds) {_reminds = reminds;}

	public void setAutoMode(boolean autoMode, String userName, String password)
	{
		_autoMode = autoMode;
		_id = userName;
		_pwd = password;
	}

	public void setAppSource(int count)
	{
		APP_KEY = WeiboConfig.client_IDS[count];
		APP_SECRET = WeiboConfig.client_SECRETS[count];
		REDIRECT_URI = count > 2 ? WeiboConfig.redirect_URI_JieYi : WeiboConfig.redirect_URI_Mine;
	}

	private String getClientId() {return APP_KEY;}

	private String getClientSecret() {return APP_SECRET;}

	private String getRedirectUri() {return REDIRECT_URI;}

	public boolean isAutoMode() {return _autoMode;}

	//public void setStatusCount(int count) {STATUS_COUNT = StatusCount.choicesStatusCount[count];}

	//public void setRepostCount(int count) {REPOST_COUNT = RepostCount.choicesRepostCount[count];}

	//public void setSuggestionCount(int count) {SUGGESTION_COUNT = SuggestionCount.choicesSuggestionCount[count];}

	public void setAccessToken(String accessToken) {_accessToken = accessToken;}

	public String getAccessToken() {return _accessToken;}

	public void setExpireTimeMillis(long expiresIn) {_expireTimeMillis = expiresIn;}

	public long getExpireTimeMillis() {return _expireTimeMillis;}

	public void setUserId(String uid) {_uid = uid;}

	public long getUserId() {return Long.parseLong(_uid);}

	public String getUserIdStr() {return _uid;}

	public boolean hasAccessToken()
	{
		String at = getAccessToken();

		return ((at != null) && !at.trim().equalsIgnoreCase(""));
	}

	public void refreshAccessToken() throws WeiboException
	{
		synchronized (ACCESS_TOKEN_LOCK)
		{
			setAccessToken(null);

			if (Application.isEventDispatchThread())
			{
				UiApplication.getUiApplication().pushModalScreen(new LoginScreen());

				synchronized (ACCESS_TOKEN_LOCK) {ACCESS_TOKEN_LOCK.notify();}					
			} else {
				UiApplication.getApplication().invokeLater(new Runnable() {
					public void run() {
						UiApplication.getUiApplication().pushModalScreen(new LoginScreen());

						synchronized (ACCESS_TOKEN_LOCK) {ACCESS_TOKEN_LOCK.notify();}
					}
				});
			}
		}
	}

	/**
	 * 判断访问令牌是否有效<br />
	 * <b>判断方法：</b>令牌不为null 且 过期时间不为0 且 当前时间小于过期时间
	 */
	private boolean isAccessTokenValid()
	{
		return ((getAccessToken() != null) && (getExpireTimeMillis() > 0) && (System.currentTimeMillis() < getExpireTimeMillis()));
	}

	private StringBuffer checkResponse(StringBuffer res) throws WeiboException
	{
		if ((res != null) && (res.length() > 0))
		{
			if ((res.charAt(0) == '{') && (res.charAt(res.length() - 1) == '}'))
			{
				JSONObject jsonObject;
				try {
					jsonObject = new JSONObject(new JSONTokener(res.toString()));

					if (!jsonObject.optString("error_code").equals(""))
					{
						String request = jsonObject.optString("request");
						String error_code = jsonObject.optString("error_code");
						String error = jsonObject.optString("error");

						if (error_code.equals("21327") || error_code.equals("21317"))
						{
							refreshAccessToken();
							return null;
						} else if (error_code.equals("20101")) {
							Function.errorDialog("目标微博不存在！");
							return null;
						} else if (error_code.equals("20704")) {
							Function.errorDialog("您已收藏此微博！");
							return null;
						}

						throw new WeiboException("\n如果你看到这个错误提示，请务必联系我，把下边的内容描述给我，谢谢了！" +
												 "\n\n\u2022 request: " + request +
												 "\n\u2022 error_code: " + error_code +
												 "\n\u2022 error: " + error
												);
					}
				} catch (JSONException e) {}
			} else {
				throw new UnknownException("\n如果你看到这个错误提示，请务必联系我，把下边的内容描述给我，谢谢了！\n" + res.toString());
			}
		}

		return res;
	}

	private JSONObject doRequest(String methond, String api, Hashtable args) throws WeiboException
	{
		synchronized (ACCESS_TOKEN_LOCK)
		{
			if (!isAccessTokenValid())
			{
				refreshAccessToken();

				try {
					ACCESS_TOKEN_LOCK.wait(WeiboConfig.AUTHORIZE_TIMEDOUT);
				} catch (InterruptedException e) {}
			}
		}

		if (!hasAccessToken())
		{
			final Screen activeScreen = UiApplication.getUiApplication().getActiveScreen();
			if (activeScreen instanceof LoginScreen)
			{
				UiApplication.getUiApplication().invokeLater(new Runnable()
				{
					public void run()
					{
						UiApplication.getUiApplication().popScreen(activeScreen);
					}
				});
			}

			try {
				throw new WeiboException(getResString(MESSAGE_ERROR_UNABLE_REFRESH_ACCESSTOKEN));
			} catch (WeiboException e) {}
		}

		JSONObject result = null;
		StringBuffer responseBuffer = null;

		if (args.get("access_token") == null) {args.put("access_token", getAccessToken());}

		try {
			if (methond.equals(HttpConnection.POST))
			{
				responseBuffer = checkResponse(http.doPost(api, args));	
			} else {
				responseBuffer = checkResponse(http.doGet(api, args));
			}

			if ((responseBuffer == null) || (responseBuffer.length() <= 0))
			{
				result = null;
			} else {
				result = new JSONObject(new JSONTokener(new String(responseBuffer.toString().getBytes(), "utf-8")));	
			}
		} catch (Exception e) {
			throw new WeiboException(e.getMessage());
		} catch (Throwable t) {
			throw new WeiboException(t.getMessage());
		}

		return result;
	}

	private String doRequestString(String methond, String api, Hashtable args) throws WeiboException
	{
		synchronized (ACCESS_TOKEN_LOCK)
		{
			if (!isAccessTokenValid())
			{
				refreshAccessToken();

				try {
					ACCESS_TOKEN_LOCK.wait(WeiboConfig.AUTHORIZE_TIMEDOUT);
				} catch (InterruptedException e) {}
			}
		}

		if (!hasAccessToken())
		{
			final Screen activeScreen = UiApplication.getUiApplication().getActiveScreen();
			if (activeScreen instanceof LoginScreen)
			{
				UiApplication.getUiApplication().invokeLater(new Runnable()
				{
					public void run()
					{
						UiApplication.getUiApplication().popScreen(activeScreen);
					}
				});
			}

			try {
				throw new WeiboException(getResString(MESSAGE_ERROR_UNABLE_REFRESH_ACCESSTOKEN));
			} catch (WeiboException e) {}
		}

		String result = null;
		StringBuffer responseBuffer = null;

		if (args.get("access_token") == null) {args.put("access_token", getAccessToken());}

		try {
			if (methond.equals(HttpConnection.POST))
			{
				responseBuffer = http.doPost(api, args);	
			} else {
				responseBuffer = http.doGet(api, args);
			}

			if ((responseBuffer == null) || (responseBuffer.length() <= 0)) {result = null;}

			result = new String(responseBuffer.toString().getBytes(), "utf-8");
		} catch (Exception e) {
			throw new WeiboException(e.getMessage());
		} catch (Throwable t) {
			throw new WeiboException(t.getMessage());
		}

		return result;
	}

	public byte[] doRequestRAW(String url)
	{
		byte[] result = null;
		StringBuffer responseBuffer = new StringBuffer();
		MyConnectionFactory _factory = new MyConnectionFactory();
		HttpConnection _conn = null;

		if (url.equals("")) {return null;}

		ConnectionDescriptor connd = _factory.getConnection(url);

		if (connd == null) {return null;}

		try {
			_conn = (HttpConnection) connd.getConnection();
			_conn.setRequestProperty(HttpProtocolConstants.HEADER_CONNECTION, HttpProtocolConstants.HEADER_KEEP_ALIVE);

			int resCode = _conn.getResponseCode();

			switch (resCode)
			{
				case HttpConnection.HTTP_OK: 
				{
					InputStream inputStream = _conn.openInputStream();

					int c;
					while ((c = inputStream.read()) != -1) {responseBuffer.append((char) c);}
					inputStream.close();

					break;
				}
			}

			result = responseBuffer.toString().getBytes();
		} catch (IOException e) {
		} finally {
			if (_conn != null) {try {_conn.close(); _conn = null;} catch (IOException e) {}}
		}

		return result;
	}

	/**
	 * 注销当前用户
	 */
	public boolean SignOut()
	{
		boolean result = false;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		String api = WeiboConfig.revokeOauth2URL;
		try {
			jsonObject = doRequest(HttpConnection.GET, api, args);

			if (jsonObject != null && !jsonObject.isNull("result"))
			{
				String resultValue = jsonObject.optString("result");
				result = resultValue.equalsIgnoreCase("true") ? true : false;
			}
		} catch (WeiboException e) {}

		return result;
	}

	private Account getAccount(JSONObject jsonObject) throws WeiboException {return new WeiboAccount(this, jsonObject);}
	/**
	 * 获取用户uid
	 */
	public Account getAccount(final AsyncCallback listener, final Object state)
	{
		if (listener != null) {
			new Thread() {
				public void run() {
					try {
						Account result = null;
						result = getAccount(null, null);
						listener.onComplete(result, null);
					} catch (Exception e) {
						listener.onException(e, null);
					}
				}
			}.start();

			return null;
		} else {
			Account result = null;
			JSONObject jsonObject = new JSONObject();
			Hashtable args = new Hashtable();

			try {
				String api = WeiboConfig.apiBaseURL + WeiboConfig.queryAccountUrl;
				jsonObject = doRequest(HttpConnection.GET, api, args);

				result = (jsonObject != null ? getAccount(jsonObject) : null);
			} catch (WeiboException e) {Function.errorDialog(e.toString());}

			return result;
		}
	}

	private Status updateStatus(JSONObject jsonObject) throws WeiboException {return new WeiboStatus(this, jsonObject);}
	/**
	 * 发送一条文字微博
	 */
	public Status updateStatus(String status)
	{
		Status result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("status", status);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryStatusUpdate;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? updateStatus(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private Status uploadStatus(JSONObject jsonObject) throws WeiboException {return new WeiboStatus(this, jsonObject);}
	/**
	 * 发送一条图文微博
	 */
	public Status uploadStatus(String status, ImageItem[] images)
	{
		Status result = null;
		StringBuffer responseBuffer = new StringBuffer();
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("status", status);

		try {
			String api = WeiboConfig.queryStatusUpload;

			responseBuffer = checkResponse(doUpload(api, args, images));
			if ((responseBuffer == null) || (responseBuffer.length() <= 0)) {result = null;}

			jsonObject = new JSONObject(new JSONTokener(new String(responseBuffer.toString().getBytes(), "utf-8")));
			result = (jsonObject != null ? uploadStatus(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());
		} catch (UnsupportedEncodingException e) {
		} catch (JSONException e) {
		}

		return result;
	}

	private StringBuffer doUpload(String url, Hashtable params, ImageItem[] images)
	{
		URLEncodedPostData encoder = new URLEncodedPostData("UTF-8", false);
		Enumeration keysEnum = params.keys();

		encoder = new URLEncodedPostData("UTF-8", false);
		keysEnum = params.keys();

		while (keysEnum.hasMoreElements()) {
			String key = (String) keysEnum.nextElement();
			String val = (String) params.get(key);
			encoder.append(key, val);
		}

		return doUpload(url, encoder, images);
	}

	private StringBuffer doUpload(String url, URLEncodedPostData textData, ImageItem[] imageData)
	{
		final String twoHyphens = "--";
		final String Boundary = "****************75b3bf4ed6a67958"; //another_weibo_image_upload_method UIDGenerator.getUniqueScopingValue()
		final String lineEnd = "\r\n";

		MyConnectionFactory factory = new MyConnectionFactory();
	    OutputStream output = null;
	    StringBuffer buffer = new StringBuffer();
		HttpConnection conn = null;

		factory.setConnectionMode(ConnectionFactory.ACCESS_READ_WRITE);
		ConnectionDescriptor descriptor = factory.getConnection(url);

        conn = (HttpConnection) descriptor.getConnection();
        if (conn == null) {Function.errorDialog("error open http connection!"); return null;}

		try
		{
			conn.setRequestMethod(HttpConnection.POST);
			conn.setRequestProperty(HttpProtocolConstants.HEADER_CONNECTION, HttpProtocolConstants.HEADER_KEEP_ALIVE);
			conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE, HttpProtocolConstants.CONTENT_TYPE_MULTIPART_FORM_DATA + "; boundary=" + Boundary);

			int length = textData.getBytes().length;

			for (int i=0; i<9; i++)
			{
				if (imageData[i] != null)
				{
					length += imageData[i].getContent().length;					
				}
			}

			conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH, Integer.toString(length));
			conn.setRequestProperty( "x-rim-transcode-content", "none" );
			conn.setRequestProperty(HttpProtocolConstants.HEADER_AUTHORIZATION, "OAuth2 " + getAccessToken());

			output = conn.openOutputStream();

			//insert IMAGE
			for (int i=0; i<9; i++)
			{
				if (imageData[i] != null)
				{
					StringBuffer imageBuffer = new StringBuffer();
					imageBuffer.append(twoHyphens + Boundary + lineEnd);
					imageBuffer.append("Content-Disposition: form-data; name=\"pic\"; filename=\"" + imageData[i].getFilename() + "\"" + lineEnd);
					imageBuffer.append("Content-Type: " + imageData[i].getContentType() + lineEnd);
					imageBuffer.append(lineEnd);

		            output.write(imageBuffer.toString().getBytes());
		            output.write(imageData[i].getContent(), 0, imageData[i].getContent().length);
		            output.write(lineEnd.getBytes());					
				}
			}

            //insert TEXT
            StringBuffer statusBuffer = new StringBuffer();

    		statusBuffer.append(twoHyphens + Boundary + lineEnd);  
            String[] temp = StringUtility.split(textData.toString(), "=");
            statusBuffer.append("Content-Disposition: form-data; name=\"" + temp[0] + "\"" + lineEnd);  
            statusBuffer.append(lineEnd);  
            statusBuffer.append(temp[1] + lineEnd);

            output.write(statusBuffer.toString().getBytes());
            output.write((twoHyphens + Boundary + twoHyphens + lineEnd).getBytes());

            output.flush();
            output.close();

			int resCode = conn.getResponseCode();

			switch (resCode)
			{
				case HttpConnection.HTTP_OK:
					InputStream inputStream = conn.openInputStream();
					int c;

					while ((c = inputStream.read()) != -1) {buffer.append((char) c);}
					inputStream.close();

					break;
			}
		} catch (IOException e) {
			Function.errorDialog(e.toString());
		} finally {
        	if(conn!=null) {try {conn.close();} catch (Exception e) {}}  
        	if(output!=null) {try {output.close();} catch (Exception e) {}}
		}

		return buffer;
	}

	private Status repostStatus(JSONObject jsonObject) throws WeiboException {return new WeiboStatus(this, jsonObject);}
	//public Status repostStatus(String id) {return repostStatus(id, "转发微博", NeedComment.NONE);}
	//public Status repostStatus(String id, String status) {return repostStatus(id, status, NeedComment.NONE);}
	/**
	 * 转发一条微博
	 */
	public Status repostStatus(String id, String status, String is_comment)
	{
		Status result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("id", id);
		args.put("status", status);
		args.put("is_comment", is_comment);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryRepostStatus;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? repostStatus(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private Comment replyStatus(JSONObject jsonObject) throws WeiboException {return new WeiboComment(this, jsonObject);}
	//public Status repostStatus(String id) {return repostStatus(id, "转发微博", NeedComment.NONE);}
	//public Status repostStatus(String id, String status) {return repostStatus(id, status, NeedComment.NONE);}
	/**
	 * 评论一条微博
	 */
	public Comment replyStatus(String id, String comment, String comment_ori)
	{
		Comment result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("id", id);
		args.put("comment", comment);
		args.put("comment_ori", comment_ori);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryCommentCreate;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? replyStatus(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private Comment replyComment(JSONObject jsonObject) throws WeiboException {return new WeiboComment(this, jsonObject);}
	//public Status repostStatus(String id) {return repostStatus(id, "转发微博", NeedComment.NONE);}
	//public Status repostStatus(String id, String status) {return repostStatus(id, status, NeedComment.NONE);}
	/**
	 * 回复一条评论
	 */
	public Comment replyComment(String id, String cid, String comment, String comment_ori)
	{
		Comment result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("id", id);
		args.put("cid", cid);
		args.put("comment", comment);
		args.put("without_mention", "1");
		args.put("comment_ori", comment_ori);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryCommentReply;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? replyComment(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private StatusWrapper getPublicTimeline(JSONObject jsonObject) throws WeiboException {return new WeiboStatusWrapper(this, jsonObject);}
	//public StatusWrapper getPublicTimeline() {return getPublicTimeline(STATUS_COUNT);}
	public StatusWrapper getPublicTimeline(String count)
	{
		StatusWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryPublicTimeline;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getPublicTimeline(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private FavoriteWrapper getFavorites(JSONObject jsonObject) throws WeiboException {return new WeiboFavoriteWrapper(this, jsonObject);}
	//public StatusWrapper getPublicTimeline() {return getPublicTimeline(STATUS_COUNT);}
	public FavoriteWrapper getFavorites(String count, String page)
	{
		FavoriteWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);
		args.put("page", page);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFavorites;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getFavorites(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private FavoriteWrapper getFavoritesByTags(JSONObject jsonObject) throws WeiboException {return new WeiboFavoriteWrapper(this, jsonObject);}
	//public StatusWrapper getPublicTimeline() {return getPublicTimeline(STATUS_COUNT);}
	public FavoriteWrapper getFavoritesByTags(String tid, String count, String page)
	{
		FavoriteWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("tid", tid);
		args.put("count", count);
		args.put("page", page);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFavoritesByTags;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getFavoritesByTags(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private GroupListWrapper getGroupList(JSONObject jsonObject) throws WeiboException {return new WeiboGroupListWrapper(this, jsonObject);}
	public GroupListWrapper getGroupList() {return getGroupList(null, null);}
	public GroupListWrapper getGroupList(final AsyncCallback listener, Object state)
	{
		if (listener != null) {
			new Thread() {
				public void run() {
					try {
						GroupListWrapper result = null;
						result = getGroupList();
						listener.onComplete(result, null);
					} catch (Exception e) {
						listener.onException(e, null);
					}
				}
			}.start();

			return null;
		} else {
			GroupListWrapper result = null;
			JSONObject jsonObject = new JSONObject();
			Hashtable args = new Hashtable();

			try {
				String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFriendshipGroups;
				jsonObject = doRequest(HttpConnection.GET, api, args);

				result = (jsonObject != null ? getGroupList(jsonObject) : null);
			} catch (WeiboException e) {Function.errorDialog(e.toString());}

			return result;
		}
	}

	private Favorite DestroyFavorites(JSONObject jsonObject) throws WeiboException {return new WeiboFavorite(this, jsonObject);}
	//public StatusWrapper getPublicTimeline() {return getPublicTimeline(STATUS_COUNT);}
	public Favorite DestroyFavorites(String id)
	{
		Favorite result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("id", id);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFavoritesDestroy;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? DestroyFavorites(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private Favorite CreateFavorites(JSONObject jsonObject) throws WeiboException {return new WeiboFavorite(this, jsonObject);}
	//public StatusWrapper getPublicTimeline() {return getPublicTimeline(STATUS_COUNT);}
	public Favorite CreateFavorites(String id)
	{
		Favorite result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("id", id);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFavoritesCreate;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? CreateFavorites(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private TagsWrapper getFavoriteTags(JSONObject jsonObject) throws WeiboException {return new WeiboTagsWrapper(this, jsonObject);}
	//public StatusWrapper getPublicTimeline() {return getPublicTimeline(STATUS_COUNT);}
	public TagsWrapper getFavoriteTags(String count, String page)
	{
		TagsWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);
		args.put("page", page);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFavoritesTags;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getFavoriteTags(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private StatusWrapper getFriendsTimeline(JSONObject jsonObject) throws WeiboException {return new WeiboStatusWrapper(this, jsonObject);}
	//public StatusWrapper getFriendsTimeline() {return getFriendsTimeline(STATUS_COUNT, "1", BaseApp.ALLAPPS, Feature.ALL, TrimUser.WHOLEFIELD);}
	public StatusWrapper getFriendsTimeline(String count, String page, String max_id) {return getFriendsTimeline(count, page, max_id, BaseApp.ALLAPPS, Feature.ALL, TrimUser.WHOLEFIELD);}
	public StatusWrapper getFriendsTimeline(String count, String page, String max_id, int base_app, int feature, int trim_user)
	{
		StatusWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);
		args.put("page", page);
		args.put("max_id", max_id);
		args.put("base_app", String.valueOf(base_app));
		args.put("feature", String.valueOf(feature));
		args.put("trim_user", String.valueOf(trim_user));

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFriendsTimeline;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getFriendsTimeline(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private StatusWrapper getGroupsTimeline(JSONObject jsonObject) throws WeiboException {return new WeiboStatusWrapper(this, jsonObject);}
	public StatusWrapper getGroupsTimeline(String list_id, String count, String page, String max_id) {return getGroupsTimeline(list_id, count, page, max_id, BaseApp.ALLAPPS, Feature.ALL);}
	public StatusWrapper getGroupsTimeline(String list_id, String count, String page, String max_id, int base_app, int feature)
	{
		StatusWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("list_id", list_id);
		args.put("count", count);
		args.put("page", page);
		args.put("max_id", max_id);
		args.put("base_app", String.valueOf(base_app));
		args.put("feature", String.valueOf(feature));

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFriendshipGroupsTimeline;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getGroupsTimeline(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private StatusWrapper getUserTimeline(JSONObject jsonObject) throws WeiboException {return new WeiboStatusWrapper(this, jsonObject);}
	public StatusWrapper getUserTimeline(String uid, String count, String page, String max_id) {return getUserTimeline(uid, count, page, max_id, BaseApp.ALLAPPS, Feature.ALL, TrimUser.WHOLEFIELD);}
	public StatusWrapper getUserTimeline(String uid, String count, String page, String max_id, int base_app, int feature, int trim_user)
	{
		StatusWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		//if ((uid == 0 && screen_name.equalsIgnoreCase("")) || (uid > 0 && screen_name.length() > 0))
		//{
		//	try {
		//		throw new WeiboException("uid和screen_name只能二选一！");
		//	} catch (WeiboException e) {}
		//}

		//if (uid > 0) {args.put("uid", String.valueOf(uid));}
		//if (screen_name.length() > 0) {args.put("screen_name", screen_name);}
		args.put("uid", uid);
		args.put("count", count);
		args.put("page", page);
		args.put("max_id", max_id);
		args.put("base_app", String.valueOf(base_app));
		args.put("feature", String.valueOf(feature));
		args.put("trim_user", String.valueOf(trim_user));

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryUserTimeline;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getUserTimeline(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	/*
	private StatusWrapper getMyTimeline(JSONObject jsonObject) throws WeiboException {return new WeiboStatusWrapper(this, jsonObject);}
	//public StatusWrapper getMyTimeline() {return getMyTimeline(STATUS_COUNT, 1, BaseApp.ALLAPPS, Feature.ALL, TrimUser.WHOLEFIELD);}
	public StatusWrapper getMyTimeline(int count, int page, int base_app, int feature, int trim_user)
	{
		StatusWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", String.valueOf(count));
		args.put("page", String.valueOf(page));
		args.put("base_app", String.valueOf(base_app));
		args.put("feature", String.valueOf(feature));
		args.put("trim_user", String.valueOf(trim_user));

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryUserTimeline;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getMyTimeline(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}
	*/

	private RepostWrapper getRepostTimeline(JSONObject jsonObject) throws WeiboException {return new WeiboRepostWrapper(this, jsonObject);}
	public RepostWrapper getRepostTimeline(long id) {return getRepostTimeline(id, REPOST_COUNT, 1, null, null);}
	/**
	 * 获取一条微博的转发列表
	 */
	public RepostWrapper getRepostTimeline(final long id, final int count, final int page, final AsyncCallback listener, Object state)
	{
		if (listener != null) {
			new Thread() {
				public void run() {
					try {
						RepostWrapper result = null;
						result = getRepostTimeline(id, count, page, null, null);
						listener.onComplete(result, null);
					} catch (Exception e) {
						listener.onException(e, null);
					}
				}
			}.start();

			return null;
		} else {
			RepostWrapper result = null;
			JSONObject jsonObject = new JSONObject();
			Hashtable args = new Hashtable();

			args.put("id", String.valueOf(id));
			args.put("count", String.valueOf(count));
			args.put("page", String.valueOf(page));

			try {
				String api = WeiboConfig.apiBaseURL + WeiboConfig.queryRepostTimeline;
				jsonObject = doRequest(HttpConnection.GET, api, args);

				result = (jsonObject != null ? getRepostTimeline(jsonObject) : null);
			} catch (WeiboException e) {Function.errorDialog(e.toString());}

			return result;
		}
	}

	private CommentWrapper getCommentsTimeline(JSONObject jsonObject) throws WeiboException {return new WeiboCommentWrapper(this, jsonObject);}
	public CommentWrapper getCommentsTimeline(long id) {return getCommentsTimeline(id, REPOST_COUNT, 1, null, null);}
	/**
	 * 获取一条微博的评论列表
	 */
	public CommentWrapper getCommentsTimeline(final long id, final int count, final int page, final AsyncCallback listener, Object state)
	{
		if (listener != null) {
			new Thread() {
				public void run() {
					try {
						CommentWrapper result = null;
						result = getCommentsTimeline(id, count, page, null, null);
						listener.onComplete(result, null);
					} catch (Exception e) {
						listener.onException(e, null);
					}
				}
			}.start();

			return null;
		} else {
			CommentWrapper result = null;
			JSONObject jsonObject = new JSONObject();
			Hashtable args = new Hashtable();

			args.put("id", String.valueOf(id));
			args.put("count", String.valueOf(count));
			args.put("page", String.valueOf(page));

			try {
				String api = WeiboConfig.apiBaseURL + WeiboConfig.queryCommenTimeline;
				jsonObject = doRequest(HttpConnection.GET, api, args);

				result = (jsonObject != null ? getCommentsTimeline(jsonObject) : null);
			} catch (WeiboException e) {Function.errorDialog(e.toString());}

			return result;
		}
	}

	private StatusWrapper getStatusMentions(JSONObject jsonObject) throws WeiboException {return new WeiboStatusWrapper(this, jsonObject);}
	/**
	 * 获取@我的微博
	 */
	//public StatusWrapper getStatusMentions() {return getStatusMentions(STATUS_COUNT, 1);}
	public StatusWrapper getStatusMentions(String count, String page, String max_id)
	{
		StatusWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);
		args.put("page", page);
		args.put("max_id", max_id);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryStatusMentions;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getStatusMentions(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private CommentWrapper getCommentMentions(JSONObject jsonObject) throws WeiboException {return new WeiboCommentWrapper(this, jsonObject);}
	/**
	 * 获取@我的评论
	 */
	//public CommentWrapper getCommentMentions() {return getCommentMentions(STATUS_COUNT, 1);}
	public CommentWrapper getCommentMentions(String count, String page, String max_id)
	{
		CommentWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);
		args.put("page", page);
		args.put("max_id", max_id);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryCommentMentions;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getCommentMentions(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private CommentWrapper getCommentToMe(JSONObject jsonObject) throws WeiboException {return new WeiboCommentWrapper(this, jsonObject);}
	/**
	 * 获取我收到的评论
	 */
	//public CommentWrapper getCommentToMe() {return getCommentToMe(STATUS_COUNT, 1);}
	public CommentWrapper getCommentToMe(String count, String page, String max_id)
	{
		CommentWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);
		args.put("page", page);
		args.put("max_id", max_id);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryCommentToMe;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getCommentToMe(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private CommentWrapper getCommentByMe(JSONObject jsonObject) throws WeiboException {return new WeiboCommentWrapper(this, jsonObject);}
	/**
	 * 获取我发出的评论
	 */
	//public CommentWrapper getCommentByMe() {return getCommentByMe(STATUS_COUNT, 1);}
	public CommentWrapper getCommentByMe(String count, String page, String max_id)
	{
		CommentWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("count", count);
		args.put("page", page);
		args.put("max_id", max_id);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryCommentByMe;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getCommentByMe(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private User getUserInfo(JSONObject jsonObject) throws WeiboException {return new WeiboUser(this, jsonObject);}
	/**
	 * 获取用户信息
	 */
	public User getUserInfo(long uid, String screen_name)
	{
		User result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		if ((uid == 0 && screen_name.equals("")) || (uid > 0 && screen_name.length() > 0))
		{
			try {
				throw new WeiboException("uid和screen_name只能二选一！");
			} catch (WeiboException e) {}
		}

		if (uid > 0) {args.put("uid", String.valueOf(uid));}
		if (screen_name != null) {args.put("screen_name", StringUtility.encode(screen_name));}

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryUserInfo;
			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getUserInfo(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private UserWrapper getUserList(JSONObject jsonObject) throws WeiboException {return new WeiboUserWrapper(this, jsonObject);}
	//public UserWrapper getUserList(int type, String uid, String count, String cursor) {return getUserList(type, uid, , STATUS_COUNT, 0, TrimStatus.WHOLEFIELD);}
	public UserWrapper getUserList(int type, String uid, String count, String cursor) //, int trim_status)
	{
		UserWrapper result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("uid", uid);
		args.put("count", count);
		args.put("cursor", cursor);
		args.put("trim_status", "1"); //只返回status_id，不需要微博内容详情

		try {
			String api = WeiboConfig.apiBaseURL;

			switch (type)
			{
				case UserList.FRIENDS:
					api += WeiboConfig.queryFriendshipFriends;
					break;
				case UserList.FOLLOWERS:
					api += WeiboConfig.queryFriendshipFollowers;
					break;
			}

			jsonObject = doRequest(HttpConnection.GET, api, args);

			result = (jsonObject != null ? getUserList(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private User CreateFriendship(JSONObject jsonObject) throws WeiboException {return new WeiboUser(this, jsonObject);}
	/**
	 * 关注一个用户
	 */
	public User CreateFriendship(String uid)
	{
		User result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("uid", uid);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFriendshipCreate;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? CreateFriendship(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private User DestroyFriendship(JSONObject jsonObject) throws WeiboException {return new WeiboUser(this, jsonObject);}
	/**
	 * 取消关注一个用户
	 */
	public User DestroyFriendship(String uid)
	{
		User result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("uid", uid);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFriendshipDestroy;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? DestroyFriendship(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private User DestroyFollower(JSONObject jsonObject) throws WeiboException {return new WeiboUser(this, jsonObject);}
	/**
	 * 移除一个粉丝
	 */
	public User DestroyFollower(String uid)
	{
		User result = null;
		JSONObject jsonObject = new JSONObject();
		Hashtable args = new Hashtable();

		args.put("uid", uid);

		try {
			String api = WeiboConfig.apiBaseURL + WeiboConfig.queryFllowerDestroy;
			jsonObject = doRequest(HttpConnection.POST, api, args);

			result = (jsonObject != null ? DestroyFollower(jsonObject) : null);
		} catch (WeiboException e) {Function.errorDialog(e.toString());}

		return result;
	}

	private SuggestionWrapper getSuggestionAtUser(String stringObject) throws WeiboException {return new WeiboSuggestionWrapper(this, stringObject);}
	//public SuggestionWrapper getSuggestionAtUser(String q) {return getSuggestionAtUser(q, SUGGESTION_COUNT, null, null);}
	/**
	 * 获取@用户时的联想建议
	 */
	public SuggestionWrapper getSuggestionAtUser(final String q, final String count, final AsyncCallback listener, Object state)
	{
		if (listener != null) {
			new Thread() {
				public void run() {
					try {
						SuggestionWrapper result = null;
						result = getSuggestionAtUser(q, count, null, null);
						listener.onComplete(result, null);
					} catch (Exception e) {
						listener.onException(e, null);
					}
				}
			}.start();

			return null;
		} else {
			SuggestionWrapper result = null;
			String stringObject;
			Hashtable args = new Hashtable();

			args.put("q", q);
			args.put("count", count);
			args.put("type", "0"); //联想类型：0关注，1粉丝
			args.put("range", "2"); //联想范围：0只联想关注人，1只联想关注人的备注，2全部

			try {
				String api = WeiboConfig.apiBaseURL + WeiboConfig.querySuggestAtUser;
				stringObject = doRequestString(HttpConnection.GET, api, args);

				result = (stringObject != null ? getSuggestionAtUser(stringObject) : null);
			} catch (WeiboException e) {Function.errorDialog(e.toString());}

			return result;
		}
	}

	private Remind getRemind(JSONObject jsonObject) throws WeiboException {return new WeiboRemind(this, jsonObject);}
	/**
	 * 获取用户未读消息
	 */
	public Remind getRemind() {return getRemind(null, null);}
	public Remind getRemind(final AsyncCallback listener, final Object state)
	{
		if (getUserIdStr().equalsIgnoreCase("")) {return null;}

		if (listener != null) {
			new Thread() {
				public void run() {
					try {
						Remind result = null;
						result = getRemind(null, null);
						listener.onComplete(result, null);
					} catch (Exception e) {
						listener.onException(e, null);
					}
				}
			}.start();

			return null;
		} else {
			Remind result = null;
			JSONObject jsonObject = new JSONObject();
			Hashtable args = new Hashtable();

			args.put("uid", getUserIdStr());
			try {
				String api = WeiboConfig.rmBaseURL + WeiboConfig.queryRemind;
				jsonObject = doRequest(HttpConnection.GET, api, args);

				result = (jsonObject != null ? getRemind(jsonObject) : null);
			} catch (WeiboException e) {Function.errorDialog(e.toString());}

			return result;
		}
	}

	/**
	 * 对当前登录用户某一种消息未读数进行清零
	 */
	public boolean setRemindCount(String type) {return setRemindCount(type, null, null);}
	public boolean setRemindCount(final String type, final AsyncCallback listener, final Object state)
	{
		if (listener != null) {
			new Thread() {
				public void run() {
					try {
						boolean result = false;
						result = setRemindCount(type, null, null);
						listener.onComplete(result, null);
					} catch (Exception e) {
						listener.onException(e, null);
					}
				}
			}.start();

			return false;
		} else {
			boolean result = false;
			JSONObject jsonObject = new JSONObject();
			Hashtable args = new Hashtable();

			args.put("type", type);
			try {
				String api = WeiboConfig.rmBaseURL + WeiboConfig.queryRemindSetCount;
				jsonObject = doRequest(HttpConnection.POST, api, args);

				if (jsonObject != null && !jsonObject.isNull("result"))
				{
					String resultValue = jsonObject.optString("result");
					result = resultValue.equalsIgnoreCase("true") ? true : false;
				}
			} catch (WeiboException e) {}

			return result;
		}
	}

	protected class LoginScreen extends BrowserScreen
	{
		protected LoginScreen()
		{
			super(WeiboConfig.authorizeURL + "?client_id=" + getClientId() + "&scope=" + WeiboConfig.scopeList + "&redirect_uri=" + getRedirectUri() + "&display=mobile&response_type=code");
		}

		protected boolean hasAccessToken(String pUrl)
		{
			boolean result = false;
			String token = getAccessTokenFromUrl(pUrl);
			
			if ((token == null) || token.trim().equals(""))
			{
				result = false;
			} else {
				setAccessToken(token);
				dismiss();
				result = true;
			}
			return result;
		}

		protected boolean shouldFetchContent(BrowserFieldRequest request)
		{
			return !hasAccessToken(request.getURL());
		}

		protected boolean shouldShowContent(BrowserField pbf, Document pdoc)
		{
			return !hasAccessToken(pdoc.getDocumentURI());
		}

		protected boolean postProcessing(BrowserField pbf, Document pdoc) 
		{
			if (isAutoMode())
			{
				if ((pdoc != null))
				{
					String jsFillId = "var userId = document.forms[0].elements['userId']; userId.focus(); userId.value = '" + _id + "';";
					String jsFillPwd = "var password = document.forms[0].elements['passwd']; password.focus(); password.value = '" + _pwd + "';";
					//String jsLogin = "setTimeout(\"var obj=document.getElementsByTagName('a')[0]; var evt_l = document.createEvent('MouseEvents'); evt_l.initEvent('click', true, true); obj.dispatchEvent(evt_l);\",3000);";
					//String jsStart = "setTimeout(\"var obj1=document.getElementsByTagName('a')[0]; var evt_s = document.createEvent('MouseEvents'); evt_s.initEvent('click', true, true); obj1.dispatchEvent(evt_s);\",3000);";

					try {
						pbf.executeScript(jsFillId);
						pbf.executeScript(jsFillPwd);
						//pbf.executeScript(jsLogin);
					} catch (Exception e) {
						try {
							//pbf.executeScript(jsStart);
						} catch (Exception e2) {}
					}
				} else {
					Function.errorDialog("pdoc == null");
				}
			}

			return true;
		}

		protected String getAccessTokenFromUrl(String url)
		{
			String code = null;
			String at = null;

			if ((url != null) && !url.trim().equals(""))
			{
				int startIndex = url.indexOf("#access_token=");
				if (startIndex > -1)
				{
					startIndex++;
					int stopIndex = url.length();
					if (url.indexOf('&', startIndex) > -1) 
					{
						stopIndex = url.indexOf('&', startIndex);
					} else if (url.indexOf(';', startIndex) > -1) {
						stopIndex = url.indexOf(';', startIndex);
					}
					at = url.substring(url.indexOf('=', startIndex) + 1, stopIndex);
				} else {
					startIndex = url.indexOf("?code=");
					if (startIndex > -1) {
						startIndex++;
						int stopIndex = url.length();
						if (url.indexOf('&', startIndex) > -1) {
							stopIndex = url.indexOf('&', startIndex);
						} else if (url.indexOf(';', startIndex) > -1) {
							stopIndex = url.indexOf(';', startIndex);
						}
						code = url.substring(url.indexOf('=', startIndex) + 1, stopIndex);
						at = getAccessTokenFromCode(code);
					}
				}
			}

			return at;
		}

		protected String getAccessTokenFromCode(String pCode)
		{
			JSONObject result = null;

			if ((pCode == null) || pCode.trim().equals("")) {return null;}

			Hashtable args = new Hashtable();
			args.put("client_id", getClientId());
			args.put("client_secret", getClientSecret());
			args.put("grant_type", "authorization_code");
			args.put("redirect_uri", getRedirectUri());
			args.put("code", pCode);

			try {
				StringBuffer responseBuffer = checkResponse(http.doPost(WeiboConfig.accessTokenURL, args));

				if ((responseBuffer == null) || (responseBuffer.length() <= 0)) {return null;}

				result = new JSONObject(new JSONTokener(responseBuffer.toString()));

				setAccessToken(result.optString("access_token"));
				setExpireTimeMillis(result.optLong("expires_in") * 1000 + System.currentTimeMillis());
				_appConfig.setAccessToken(getAccessToken());
				_appConfig.setExpireTimeMillis(getExpireTimeMillis());
				_appConfig.save(null, false);
			} catch (Exception e) {
			} catch (Throwable t) {}

			return getAccessToken();
		}
	}

	private String getResString(int key) {return _bundle.getString(key);}
}